iT邦幫忙

2026 iThome 鐵人賽

DAY 7
0
ChatGPT & Codex

AI 救得了祖傳系統嗎?30 天實戰企業 Legacy System × AI 協作開發系列 第 7 篇

Day 7|真正難懂的不是程式碼,而是沒人寫下來的商業規則

  • 分享至 

  • xImage
  •  

AI 看得懂 if、看得懂 SQL,也能一路追到資料表。
但它未必知道:為什麼這個條件不能拿掉?


前言/情境導入

前一篇,我們把 AI 的分析一路追到:

畫面元件
    ↓
Dataset
    ↓
SQL / Stored Procedure
    ↓
資料表與欄位

做到這裡,我原本以為已經很接近「看懂系統」。

但真正開始修改 ERP 之後,我才發現:

找到資料從哪裡來,只回答了「系統怎麼做」。

更難的是「公司為什麼要這樣做」。

例如:

if dtDocument.FieldByName('STATUS').AsString = 'N' then
  btnEdit.Enabled := True;

AI 很容易解釋:

STATUS = 'N' 時,系統允許使用者編輯資料。

語法完全沒問題。

但如果它接著說:

N 代表「未簽核」,所以未簽核單據都可以修改。

事情就開始危險了。

因為程式碼目前只能證明:

STATUS = N
    ↓
btnEdit.Enabled = True

它沒有證明:

N = 未簽核

更沒有證明:

所有 STATUS = N 的資料都一定允許修改

這也是 Legacy System 最麻煩的地方。

AI 很會讀 Code。

但 Business Rule 往往根本沒有完整寫在 Code 裡。


核心技術解析

1. 看懂程式,不等於看懂規則

先把兩件事情拆開。

程式邏輯

程式邏輯回答的是:

如果 A 成立
    ↓
執行 B

例如:

if Status = 'N' then
  AllowEdit;

AI 對這種事情通常很擅長。

它可以解釋條件、追 Function、找變數,甚至幫我們畫出執行流程。

但 Business Rule 問的是另一件事:

為什麼 A 成立時才能執行 B?

這個「為什麼」,才是真正困難的地方。


2. Business Rule 通常散落在整套系統裡

理想狀況下,一條商業規則應該有:

需求文件
    ↓
Business Rule
    ↓
程式實作
    ↓
測試案例

但很多維護十幾年以上的系統,比較常見的是:

一部分在 Delphi
一部分在 Stored Procedure
一部分在 Trigger
一部分藏在資料欄位
還有一部分只存在資深使用者的記憶裡

例如「這張單據能不能修改」,可能同時受到:

位置 可能包含的規則
Delphi UI Edit Button 是否 Enabled
Dataset Event Post 前是否再次檢查
Stored Procedure 是否允許更新目前狀態
Trigger 阻止不合法資料異動
資料欄位 簽核、鎖定、作廢狀態
使用者流程 某些情況即使畫面能操作,也不能真的修改

所以 Search 到:

STATUS = 'N'

只能證明:

這個條件存在。

不能直接推論:

這就是完整的 Business Rule。


3. 最危險的是 AI 會替欄位名稱「補故事」

Legacy System 裡經常看到這種欄位:

MARK_1
MARK_2
STATUS
TYPE
LOCK_FLAG
YN
SEQ

有些欄位甚至連維護它很多年的人,都不敢只看名字解釋。

可是 AI 很容易根據名稱建立一個「看起來很合理」的故事。

例如看到:

if LOCK_FLAG = '' then

它可能直接解釋:

LOCK_FLAG 為空代表資料尚未鎖定,因此使用者可以修改。

問題是:

合理,不等於正確。


程式碼實作

AI 第一次翻車:它把欄位名稱當成規格書

假設我第一次只把這段程式丟給 AI:

procedure TFDocument.btnEditClick(Sender: TObject);
begin
  if dtDocument.FieldByName('LOCK_FLAG').AsString <> '' then
  begin
    ShowMessage('目前資料無法修改。');
    Exit;
  end;

  dtDocument.Edit;
end;

然後問:

請解釋 LOCK_FLAG 的用途,以及這段程式的商業規則。

⚠️ 危險的自信解讀

AI 很可能回答得像這樣:

LOCK_FLAG 是資料鎖定旗標。
空字串表示資料目前沒有被鎖定,因此允許使用者修改。

非空字串代表資料已被其他使用者或流程鎖定,所以系統會阻止編輯,以避免多人同時修改造成資料衝突。

這段回答最大的問題,不是它一定錯。

而是:

它把沒有證據的假設,講成已經確認的事實。

拆開來看會更清楚。

Code 真正能證明的是

LOCK_FLAG <> ''
    ↓
不允許進入 Edit

AI 自己補上的卻是

LOCK_FLAG 是多人編輯鎖

非空值代表其他使用者正在使用

這個設計是為了避免 concurrency

這些都有可能是真的。

但目前沒有任何證據。

這就是最危險的地方。

如果 AI 回答:

「我不知道。」

我們反而會繼續查。

但它偏偏給了一個非常合理、非常完整、甚至很像資深工程師寫出來的解釋。

工程師一旦沒有再往下驗證,就可能直接把假設當成規格。


4. 繼續追 Code,商業規則開始改寫

接著我繼續搜尋相關程式。

又找到:

procedure TFDocument.dtDocumentAfterScroll(DataSet: TDataSet);
begin
  btnEdit.Enabled :=
    dtDocument.FieldByName('STATUS').AsString = 'N';
end;

現在至少知道:

STATUS = N
    ↓
Edit Button 才能按

但按下之後還會:

LOCK_FLAG <> ''
    ↓
阻止 Edit

整條流程變成:

STATUS = N
    ↓
Edit Button Enabled
    ↓
使用者按 Edit
    ↓
檢查 LOCK_FLAG
    ↓
LOCK_FLAG = ''
    ↓
dtDocument.Edit

所以一開始:

STATUS = N → 可以修改

是不完整的。

比較精確應該是:

STATUS = N
AND
LOCK_FLAG = ''
    ↓
目前這個畫面的 Edit 入口允許修改

我刻意寫:

「目前這個畫面的 Edit 入口」

而不是:

「整套 ERP 都允許修改」

因為現在仍然沒有證明:

  • 是否還有其他修改入口;
  • Stored Procedure 是否會再檢查;
  • Trigger 是否有額外限制;
  • 歷史資料是否遵循完全相同的規則。

5. 加入 Rule Card:逼 AI 把「知道」和「猜的」分開

這次我不再問:

LOCK_FLAG 是什麼?

而是改成:

請根據目前提供的程式碼整理 Business Rule。

規則:

1. 只能列出有程式碼證據支持的結論。
2. 每一條結論要標示證據來源。
3. 根據欄位名稱推測的內容必須標示為「假設」。
4. 沒有足夠證據的地方列入「待確認」。
5. 不要自行補完欄位的商業意義。

✅ 證據導向解讀

這次我期待 AI 回答的是:

已確認

  1. STATUS = 'N' 時,btnEdit 會被設為 Enabled。
    證據:dtDocumentAfterScroll

  2. 使用者按下 Edit 後,如果 LOCK_FLAG <> '',程式會停止,不會執行 dtDocument.Edit。
    證據:btnEditClick

  3. 因此目前這個畫面的編輯入口至少受到 STATUS 與 LOCK_FLAG 兩個條件影響。

假設

LOCK_FLAG 可能與資料鎖定或流程狀態有關,但目前程式碼不足以判斷其完整商業意義。

待確認

  • STATUS = 'N' 的實際業務定義。
  • LOCK_FLAG 各個可能值的意義。
  • 是否存在其他編輯入口。
  • Stored Procedure 或 Trigger 是否還有額外限制。

兩次回答放在一起看,差異其實非常明顯。

第一次回答 加入限制後
LOCK_FLAG 是資料鎖 LOCK_FLAG 的商業意義尚未確認
非空代表其他人正在使用 只能確認非空時阻止 Edit
目的為避免多人修改 原因目前沒有證據
把推測寫成結論 把內容拆成已確認、假設、待確認

AI 並沒有突然獲得更多公司知識。

真正改變的是:

我不再允許它把空白的地方自己補滿。


AI 說

第一次:

LOCK_FLAG 是防止多人同時修改資料的鎖定機制。

第二次:

LOCK_FLAG <> '' 會阻止目前這個 Edit 流程。至於 LOCK_FLAG 是否代表多人編輯鎖,目前沒有足夠證據。


工程師判決

第二個答案才可以繼續往下用。

不是因為它說得比較完整。

而是因為它很清楚地區分:

已知
假設
未知

這三個層級。

第一個答案最大的問題不是一定錯。

而是:

AI 把「可能」講成了「就是」。


6. 我開始替 Business Rule 建立 Rule Card

所以現在遇到比較重要的商業規則,我會要求 AI 幫我整理成一張 Rule Card。

例如:

項目 內容
Rule ID BR-EDIT-001
行為 控制目前資料是否可進入編輯
已確認條件 STATUS = 'N'
第二層條件 LOCK_FLAG = ''
證據 AfterScroll、btnEditClick
未確認 STATUS = 'N' 的完整商業意義
未確認 LOCK_FLAG 每個值代表什麼
未確認 是否存在其他編輯入口
修改風險 可能影響既有資料修改權限
驗證方式 測試不同 STATUS / LOCK_FLAG 組合

Rule Card 真正有價值的地方,不是文件變漂亮了。

而是強迫我們回答四件事:

我知道什麼?
        ↓
我從哪裡知道?
        ↓
哪些只是推測?
        ↓
還有哪些不知道?

而且這張卡片不會停在這裡。

下一步我會直接把它再次交給 AI,當成新的 Context:

根據 BR-EDIT-001,目前還有以下待確認事項:

1. STATUS = N 的完整意義
2. LOCK_FLAG 各值的用途
3. 是否存在其他修改入口
4. Stored Procedure / Trigger 是否有額外限制

請只針對以上未知項目繼續追查,
並為每個結論提供程式碼或 SQL 證據。

接著可能去:

搜尋 Stored Procedure
        ↓
查看 Trigger
        ↓
檢查其他 Form
        ↓
比對歷史資料
        ↓
詢問資深使用者
        ↓
把確認結果更新回 Rule Card

這樣 Rule Card 就不是一次性的分析結果。

它會變成一份持續更新的:

Business Rule Context。

每確認一件事,就把「未知」移到「已確認」。

每發現新的問題,就繼續加入「待確認」。

最後得到的不是 AI 自己編出來的規格書,而是:

一份有證據逐步長出來的規格。


7. 除了程式證據鏈,還需要 Business Rule 證據鏈

上一篇我們建立的是:

UI
↓
Dataset
↓
SQL
↓
Database

但 Business Rule 還要繼續往外追:

程式條件
    ↓
其他呼叫位置
    ↓
相關欄位
    ↓
Stored Procedure / Trigger
    ↓
實際操作流程
    ↓
歷史資料
    ↓
使用者或需求確認

不代表每個問題都必須一路查到底。

但規則越重要,我就會要求越多證據。

特別是碰到:

金額
簽核
權限
刪除
編號
狀態
跨資料表同步

這些地方時,更不能只憑一段 Code 就宣布:

「我找到 Business Rule 了。」


8. 把「不知道」也放進 Context

第三篇建立 Context Pack 時,我們整理過:

問題現象
↓
操作步驟
↓
錯誤訊息
↓
相關 Event
↓
Dataset / SQL
↓
Schema

現在我會再補上一塊:

Business Rules

而且不只是放「已知規則」。

還要把「未知」一起寫進去。

例如:

【已知商業規則】

1. STATUS = 'N' 時,目前畫面的 Edit Button 可以按。

2. 實際進入 Edit 前,
   還會檢查 LOCK_FLAG 是否為空。

3. 本次需求只允許調整 Edit 判斷,
   不允許修改其他流程。


【目前未知】

1. STATUS = 'N' 的完整業務定義。

2. LOCK_FLAG 所有可能值的意義。

3. 是否還有其他畫面可以修改同一筆資料。

4. Database 是否還有第二層防護。


【AI 回答限制】

對未知事項不得自行推論為既定規則;
若需要做假設,必須明確標記為「假設」。

以前我會覺得:

Prompt 裡寫「不知道」,是不是代表提供的 Context 不夠完整?

現在我反而認為:

能夠明確指出自己不知道什麼,本身就是 Context Engineering 的一部分。

因為最危險的不是資料不足。

而是:

資料不足
    +
AI 自動補完
    +
工程師沒發現它在猜

9. 為什麼我不希望 AI 幫我「順便重構」

當 AI 覺得自己已經理解 Business Rule,很容易開始提出:

建議把 LOCK_FLAG 改成 Boolean。

建議把 STATUS 統一改成 Enum。

建議把這些判斷集中成一個 Method。

建議移除重複條件。

建議重新整理整套狀態管理。

從程式設計角度看,很多建議甚至沒有錯。

問題是它不知道:

  • 十年前的資料長什麼樣子;
  • 其他程式是不是直接讀這些欄位;
  • 報表是不是依賴某個特殊值;
  • 外部系統是不是已經把某種怪異狀態當成正式格式。

Legacy System 有一個很麻煩的特性:

今天看起來像 Bug 的東西,十年後可能已經變成 Business Rule。

所以在證明以前,我不希望 AI 因為:

「這樣寫比較漂亮。」

就把它順手改掉。


不會 Delphi,你可以帶走什麼?

這篇其實幾乎跟 Delphi 無關。

不論維護 Java、C#、PHP、Python、COBOL,或任何企業舊系統,都可以帶走三件事。

1. Code 可以證明「系統怎麼做」,不一定能證明「公司為什麼這樣做」

STATUS = N

是程式事實。

N = 未簽核

則需要另外證明。


2. Search Hit 不等於 Business Rule

找到一個條件只是線索。

真正的規則可能散落在:

UI
Database
Workflow
Historical Data
User Knowledge

3. AI 說「不知道」有時比完整回答更有價值

如果證據不足:

「目前無法確認。」

不是一個差答案。

反而可能是 Legacy System 裡最安全的答案之一。


今日小結

前六天,我一直在想辦法讓 AI 看懂 Legacy Code。

到了今天,我反而開始覺得:

語法可能是整套 Legacy System 裡最簡單的部分。

真正困難的是:

這個欄位為什麼存在?

這個判斷為什麼不能拿掉?

十年前的資料是不是例外?

還有沒有另一條流程?

這到底是程式設計,
還是已經變成公司規則?

所以今天替 AI Agent 再增加一條規則:

不要只告訴我 Code 在做什麼。

請把「已確認」、「假設」與「未知」分開。

因為維護 Legacy System 時,最危險的 AI 不一定是回答錯誤。

而是:

它只看到一小段 Code,卻替整套系統寫出了一個非常合理的故事。

下一篇,就要開始碰一個很典型的 ERP 問題。

需求聽起來只有一句:

「這個編號規則要改一下。」

但真的開始往下追之後才會發現:

你以為只是在改一個欄位,實際上可能動到主檔、明細、簽核、報表,甚至整條資料生命週期。


上一篇
Day 6|AI 說「資料來自這張表」,證據呢?建立 Legacy Code 證據鏈
下一篇
Day 8|流水號從三碼改四碼,為什麼不能只改欄位?
系列文
AI 救得了祖傳系統嗎?30 天實戰企業 Legacy System × AI 協作開發 共 11 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言